﻿namespace BM.Tools.WebControls.MForm.Controls.Modifiers
{
    using System;
    using System.Web.UI;

    using BM.Tools.WebControls.MForm.Controls.Items;

    /// <summary>
    /// A class that modifies <see cref="Offspring"/> object to which it is bound to, and the <see cref="OffspringItem"/> objects which are created from this <see cref="Offspring"/> definition.
    /// </summary>
    /// <typeparam name="T">
    /// The offspring type
    /// </typeparam>
    /// <typeparam name="TItem">
    /// The offspring item type
    /// </typeparam>
    public abstract class Modifier<T, TItem> where T : Offspring where TItem : OffspringItem
    {
        internal void OnBasisInitInternal(object sender, EventArgs e)
        {
            OnBasisInit(sender as T, e);
        }

        internal void OnBasisLoadInternal(object sender, EventArgs e)
        {
            OnBasisLoad(sender as T, e);
        }

        internal void OnBasisPreRenderInternal(object sender, EventArgs e)
        {
            OnBasisPreRender(sender as T, e);
        }

        internal void OnItemCreatedInternal(object sender, OffspringItemEventArgs e)
        {
            e.Item.Init += OnItemInitInternal;
            e.Item.Load += OnItemLoadInternal;
            e.Item.PreRender += OnItemPreRenderInternal;
        }

        /// <summary>
        /// The method is attached to the <see cref="Offspring"/> <see cref="Control.Init"/> event handler.
        /// </summary>
        /// <param name="offspring">
        /// The offspring.
        /// </param>
        /// <param name="e">
        /// The event args.
        /// </param>
        protected virtual void OnBasisInit(T offspring, EventArgs e)
        {
        }

        /// <summary>
        /// The method is attached to the <see cref="Offspring"/> <see cref="Control.Load"/> event handler.
        /// </summary>
        /// <param name="offspring">
        /// The offspring.
        /// </param>
        /// <param name="e">
        /// The event args.
        /// </param>
        protected virtual void OnBasisLoad(T offspring, EventArgs e)
        {
        }

        /// <summary>
        /// The method is attached to the <see cref="Offspring"/> <see cref="Control.PreRender"/> event handler.
        /// </summary>
        /// <param name="offspring">
        /// The offspring.
        /// </param>
        /// <param name="e">
        /// The event args.
        /// </param>
        protected virtual void OnBasisPreRender(T offspring, EventArgs e)
        {
        }

        /// <summary>
        /// The method is attached to the <see cref="OffspringItem"/> <see cref="Control.Init"/> event handler.
        /// </summary>
        /// <param name="offspringItem">
        /// Each child item of the <see cref="Offspring"/>.
        /// </param>
        /// <param name="e">
        /// The event args.
        /// </param>
        protected virtual void OnItemInit(TItem offspringItem, EventArgs e)
        {
        }

        /// <summary>
        /// The method is attached to the <see cref="OffspringItem"/> <see cref="Control.Load"/> event handler.
        /// </summary>
        /// <param name="offspringItem">
        /// Each child item of the <see cref="Offspring"/>.
        /// </param>
        /// <param name="e">
        /// The event args.
        /// </param>
        protected virtual void OnItemLoad(TItem offspringItem, EventArgs e)
        {
        }

        /// <summary>
        /// The method is attached to the <see cref="OffspringItem"/> <see cref="Control.PreRender"/> event handler.
        /// </summary>
        /// <param name="offspringItem">
        /// Each child item of the <see cref="Offspring"/>.
        /// </param>
        /// <param name="e">
        /// The event args.
        /// </param>
        protected virtual void OnItemPreRender(TItem offspringItem, EventArgs e)
        {
        }

        private void OnItemInitInternal(object sender, EventArgs e)
        {
            OnItemInit(sender as TItem, e);
        }

        private void OnItemLoadInternal(object sender, EventArgs e)
        {
            OnItemLoad(sender as TItem, e);
        }

        private void OnItemPreRenderInternal(object sender, EventArgs e)
        {
            OnItemPreRender(sender as TItem, e);
        }
    }
}